import shelve
import sys
sys.path.append("/home/cyw/projects/function_sim_project/function_sim/")
sys.path.append("/home/cyw/projects/function_sim_project/basic_script")
from functionSim_train import functionModelWarpper
from easySample import easySample
import torch

PAIR_NAME="test"
FUNCTIONSIM_ZERO=r"/home/cyw/projects/function_sim_project/all_data/models/functionSim_zero_model.pth"
FUNTIONSIM_HETE=r"/home/cyw/projects/function_sim_project/all_data/models/functionSim_with_hete_model.pth"
FUNCTIONSIM=r"/home/cyw/projects/function_sim_project/all_data/models/functionSim_model.pth"
threshold=0.5
modelList=["functionSim","functionSim_with_hete","functionSim_zero"]
a=easySample()

def get_pair_res(modelName):
    """
        获取之前保存的mrr矩阵信息,
        这里默认的是基于test的all-to-all集合
        有用的信息如下：
            ranked_list
            ground_truth
            nameList-->每一行的主元素
            name_to_lable
    """
    res={}

    with shelve.open("/home/cyw/projects/function_sim_project/all_data/indicators/MRR/all_to_all_{}".format(modelName)) as file:
        res["ranked_list"] = file["ranked_list"]
        res["ground_truth"] = file["ground_truth"]
        res["nameList"] = file["nameList"]
        # res["res"] = file["sim_res"]
        # res["lable_to_name"] = file["lable_to_name"]
        res["name_to_lable"] = file["name_to_lable"]
    return res


def get_fn_and_fp(ranked_list,true_list,name_to_lable):
    """
        根据true_list来确定漏报误报
    """
    lth=len(true_list)
    n=len(ranked_list)
    assert lth!=0
    res={}
    res["fn"]=[]
    res["fp"]=[]
    vis={}
    for i in range(lth):
        if ranked_list[i] not in true_list:
            res["fp"].append((ranked_list[i],name_to_lable[ranked_list[i]]))
        else:
            vis[ranked_list[i]]=True   
    for name in true_list:
        if name not in vis:
            res["fn"].append((name,name_to_lable[name]))
    return res


def gene_all_infs(pairRes,save_name):
    """
        读取之前保存的mrr矩阵信息，获取fp，fn的信息
        误报  FP 负类别的样本被错误地预测为正类别。
        漏报  fn 
    """
    ranked_list=pairRes["ranked_list"]
    ground_truth=pairRes["ground_truth"]
    nameList=pairRes["nameList"]
    name_to_lable=pairRes["name_to_lable"]

    ans={}
    
    for i in range(len(ranked_list)):
        res=get_fn_and_fp(ranked_list[i],ground_truth[i],name_to_lable)
        sampleName=nameList[i]
        ans[sampleName]=res

    with shelve.open("/home/cyw/projects/function_sim_project/all_data/indicators/fpAndFn/{}_mrr".format(save_name)) as file:
        file["ans"] = ans
    return ans

def get_all_infs(save_name):
    with shelve.open("/home/cyw/projects/function_sim_project/all_data/indicators/fpAndFn/{}_mrr".format(save_name)) as file:
        ans = file["ans"]
    return ans

def show_pair_differ(data,data1):
    """
        不同样本对的对比
        前者是好的,或者是坏的
    """
    print("正在生成不同模型间的样本对")
    MUL=2
    ans={}
    resStr=[]
    hashmap={}
    for sampleName in data.keys():
        res={}
        res["fp"]=[]
        res["fn"]=[]
        for fn in data1[sampleName]['fn']:
            if fn not in data[sampleName]['fn']:
                res['fn'].append(fn)

        for fp in data1[sampleName]['fp']:
            if fp not in data[sampleName]['fp']:
                res['fp'].append(fp)
        ans[sampleName]=res

        # 这里fp和fn的数量是一致的
        lth=len(data1[sampleName]['fn'])
        lth1=len(data[sampleName]['fn'])
        str1="\t模型a：{}-{}\t模型b：{}-{}\t最终：{}-{}".\
            format(lth,lth,lth1,lth1,len(res["fn"]),len(res["fp"]))
        if lth>lth1 * MUL:
            famLable=data1[sampleName]['fn'][0][1]
            if famLable not in hashmap:
                hashmap[famLable]=[]
            hashmap[famLable].append(sampleName)
            tempStr="{}--{}:\n{}".format(famLable,sampleName,str1)
            resStr.append(tempStr)
            print(res)
    resStr.sort()
    for temp in resStr:
        print(temp)
    print("在{}倍的情况下，共{}个样本被选中".format(MUL,len(resStr)))
    for i in hashmap.keys():
        print("{}:{}".format(i,hashmap[i]))
    return ans

def func(res):
    # show_pair_differ中分析出的样本对
    hashmap={}
    # analysisPair=[]
    # data1 = ['5e9f256386b46d5d921530338af16dc0', '5f7087ec046d2783956c7cc46ee3d093', '83d7b1cfb1845c92fc1a0e9e18e7a62a', 'a56b4e8910a0657d762a1dd5b0afb207', '500f41c1333338b94656d5f6d60a41e6', '744b2d35599d52c3a8e2f7bf5255c144', '515a1d31294dae4c4d42f79ed01edbfb', 'c07972c497a751d2f1eadd622846bd68', '75aa87280c40f9e16d44a385412ae24d', '2ca9ce7764b20d0b73c58a5399a820ce', 'c375ced53c5ec2665eeed42b1da86a71', '22ae42b59150ccd01b229afa9648abbd']
    # data2 = ['00a109d00d01fc2be04738ee9dcc65c2', 'ec45bbfb38da5b65a58eb018b0122285', 'de952d92b65848b8e2e9fb6bd37c551e', '17fab1ae661728a7fc4f69e204c4625f']
    # data3 = ['b8d57a81593cf7350de0f9894cd2374b', 'd22077cf8300006eca5af8e9b6d4fcad', 'd3da82a58eac8e27ec81d23be42095cc', 'ee8f97a8df20117ddd40b931974742c6', 'f839770e3bdc06a1605a9a426e70aa4d', 'd1f5d1c8dd7b864b18110e43951fd8f4', 'b4e0c8ad5bfeea457cdb116a628b9081', 'd1306e9e6b776a3bb91a08c03da71ff3', 'ce50ffacc83a28928c01030ef2d6e5ef', 'e603676d1f932a4410e03c471ce47e0a']
    # data4 = ['114a29e92f1c0094485c69ed70fa963d', '3ea4d3a5ca08f6c2cb97f26040d0e056', '413b6cf7f0968544dd8bd98e324be586', 'd6c424014cd21334bf6e9867156912c6', '05226175a5b770f3b288f342a9925ab3', '38b44282d87246710de06e8ec643982d', 'ea39353def0cfd89d46fad0f297b091f', '5386667ee5c2882087e51d7415a6c83b', 'effe2fa9a0cb657cec2c8f4b2e5166e4', '57fc09dc59e49acbe2fd7f58d1b5aae8']
    # analysisPair.append(data2)
    # analysisPair.append(data1)
    # analysisPair.append(data3)
    # analysisPair.append(data4)

    # 移除重复的样本
    analysisPair=[]
    data1 = ["5e9f256386b46d5d921530338af16dc0","a56b4e8910a0657d762a1dd5b0afb207","500f41c1333338b94656d5f6d60a41e6"]
    data2 = ['00a109d00d01fc2be04738ee9dcc65c2', 'ec45bbfb38da5b65a58eb018b0122285']
    data3 = ['b8d57a81593cf7350de0f9894cd2374b']
    data4 = ['114a29e92f1c0094485c69ed70fa963d', '3ea4d3a5ca08f6c2cb97f26040d0e056', '413b6cf7f0968544dd8bd98e324be586', 'd6c424014cd21334bf6e9867156912c6', '05226175a5b770f3b288f342a9925ab3', '38b44282d87246710de06e8ec643982d', 'ea39353def0cfd89d46fad0f297b091f', '5386667ee5c2882087e51d7415a6c83b', 'effe2fa9a0cb657cec2c8f4b2e5166e4', '57fc09dc59e49acbe2fd7f58d1b5aae8']
    analysisPair.append(data2)
    analysisPair.append(data1)
    analysisPair.append(data3)
    analysisPair.append(data4)
    print("共需要分析{}个家族".format(len(analysisPair)))
    for nameList in analysisPair:
        print("--------------------------------")
        for name in nameList:
            tar = len(a.get_sample(name,"functionSim")["adj"])
            print("{}:{}".format(name,tar))
            print("\t******fp:")
            for cName,famLable in res[name]['fp']:
                tar = len(a.get_sample(cName,"functionSim")["adj"])
                print("\t{}--{}--{}".format(cName,famLable,tar))
            print("\t******fn:")
            for cName,famLable in res[name]['fn']:
                tar = len(a.get_sample(cName,"functionSim")["adj"])
                print("\t{}--{}--{}".format(cName,famLable,tar))
    return 0
    

if __name__ =="__main__":
    fp=0
    fn=0
    print("{:25}{:>8}{:>8}".format("model_name","fp","fn"))
    ans={}
    for name in modelList:
        pairRes=get_pair_res(name)
        gene_all_infs(pairRes,name)    
        res=get_all_infs(name)
        for sample in res.keys():
            fp+=len(res[sample]["fp"])    
            fn+=len(res[sample]["fn"])    
        print("{:25}{:>8}{:>8}".format(name,fp,fn))
        ans[name]=res

    res = show_pair_differ(ans[modelList[1]],ans[modelList[2]])
    func(res)